package com.wctj.api.business.huifu.service.handler;

import com.alibaba.fastjson.JSON;
import com.huifu.adapay.core.AdapayCore;
import com.huifu.adapay.core.util.AdapaySign;
import com.wctj.api.base.enums.ApiCode;
import com.wctj.api.base.enums.PayModeEnums;
import com.wctj.api.base.exception.CustomException;
import com.wctj.api.base.utils.JsonUtils;
import com.wctj.api.business.common.dto.DdwxPaymentMessageInfoDTO;
import com.wctj.api.business.common.helper.PayResponseHelper;
import com.wctj.api.business.common.service.DdwxPaymentMessageInfoService;
import com.wctj.api.business.common.service.PayResponse;
import com.wctj.api.business.huifu.enums.HuiFuPayStatusEnums;
import com.wctj.api.business.huifu.dto.HuiFuNoticeParamsData;
import com.wctj.api.business.huifu.dto.HuiFuRequestNoticeParams;
import com.wctj.api.infra.common.bean.NoticeParams;
import com.wctj.api.infra.web.support.HttpRequestNoticeParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;

/**
 * 汇付天下-Adapay 支付回调响应模式处理
 */
@Slf4j
@Service
public class HuiFuPayResponse implements PayResponse {
    @Resource
    private PayResponseHelper payResponseHelper;
    @Resource
    private DdwxPaymentMessageInfoService ddwxPaymentMessageInfoService;

    @Override
    public Boolean validResponse(NoticeParams noticeParams) {
        try {
            String bodyStr = StringUtils.isBlank(noticeParams.getBodyStr()) ? JsonUtils.toJson(noticeParams.getBody()) : noticeParams.getBodyStr();
            HuiFuRequestNoticeParams httpRequestNoticeParam = JSON.parseObject(bodyStr, HuiFuRequestNoticeParams.class);
            //验签请参data
            String data = httpRequestNoticeParam.getData();
            //验签请参sign
            String sign = httpRequestNoticeParam.getSign();
            //验签请参publicKey
            String publicKey = AdapayCore.PUBLIC_KEY;
            //验签
            Boolean verifySign = AdapaySign.verifySign(data, sign, publicKey);
            log.info("验签请参：data={},sign={},verifySign={}", data, sign,verifySign);
            return verifySign;
        } catch (Exception e) {
            log.error("异步回调验签异常", e);
        }
        return Boolean.FALSE;
    }

    @Override
    public String handle(HttpRequestNoticeParams requestNoticeParam) {
        NoticeParams noticeParams = this.getNoticeParams(requestNoticeParam);
        updateMsgHandle(noticeParams,null);
        if (validResponse(noticeParams)) {
            String bodyStr = StringUtils.isBlank(noticeParams.getBodyStr()) ? JsonUtils.toJson(noticeParams.getBody()) : noticeParams.getBodyStr();
            HuiFuRequestNoticeParams httpRequestNoticeParam = JSON.parseObject(bodyStr, HuiFuRequestNoticeParams.class);
            // payment.succeeded | payment.failed ....
            String type =httpRequestNoticeParam.getType();
            log.info("HuiFu handle eventType:{},{}", type,bodyStr);
            String[] eventType = type.split("\\.");
            // 事件分发各策略去处理
            payResponseHelper.eventTypeHuiFuHandle(requestNoticeParam,eventType[0]);
        } else {
            // 校验消息异常事件处理，这里需要重写，将消息处理抽出一张表来处理
            updateMsgHandle(noticeParams, HuiFuPayStatusEnums.failed);
            throw new CustomException(ApiCode.HUIFU_CALLBACK_ANALYSIS_FAIL);
        }
        return noticeParams.getBodyStr();
    }

    /**
     * 校验消息异常事件处理
     * @param noticeParams
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateMsgHandle(NoticeParams noticeParams,HuiFuPayStatusEnums status) {
        String bodyStr = StringUtils.isBlank(noticeParams.getBodyStr()) ? JsonUtils.toJson(noticeParams.getBody()) : noticeParams.getBodyStr();
        HuiFuRequestNoticeParams noticeDto = JSON.parseObject(bodyStr, HuiFuRequestNoticeParams.class);
        HuiFuNoticeParamsData data = JsonUtils.readFromString(noticeDto.getData(), HuiFuNoticeParamsData.class);
        // 开发平台创建的支付订单编号
        DdwxPaymentMessageInfoDTO recordDTO = ddwxPaymentMessageInfoService.findByPayOrderNumber(data.getOrderNo());
        if (Objects.isNull(recordDTO)){
            throw new CustomException(ApiCode.PAY_MESSAGE_ORDER_NOT_EXIST);
        }
        // 更新支付状态
        DdwxPaymentMessageInfoDTO msgDto = new DdwxPaymentMessageInfoDTO(recordDTO.getId());
        // 通知请求体
        msgDto.setNotifyRequestMsg(bodyStr);
        if (Objects.nonNull(status)){
            msgDto.setStatus(status.getCode());
        }
        ddwxPaymentMessageInfoService.updateById(msgDto);
        log.error("回调接收异常消息：对 HTTP 回调参数进行签名验证失败！bodyStr:{}", noticeParams.getBodyStr());
    }


    @Override
    public PayModeEnums getPayMode() {
        return PayModeEnums.huifu_adapay;
    }
}
